package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.PageUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanhua.common.enums.TitleStateType;
import com.tanhua.common.enums.TotalsStateType;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.server.api.MessagesApi;
import com.tanhua.dubbo.server.api.QuanZiApi;
import com.tanhua.dubbo.server.pojo.MsgQuery;
import com.tanhua.dubbo.server.pojo.Publish;
import com.tanhua.server.vo.MessagesVo;
import com.tanhua.server.vo.MsgVo;
import com.tanhua.server.vo.PageMessagesVo;
import com.tanhua.server.vo.TotalsVo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MessagesService {

    @Reference
    private MessagesApi messagesApi;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Reference
    private QuanZiApi quanZiApi;

    /**
     * 消息通过
     *
     * @return
     */
    public String messagesPass(String[] ids) {
        String msg = messagesApi.messagesPass(ids);
        return msg;
    }

    /**
     * 消息置顶
     *
     * @param id
     * @return
     */
    public String messagesTop(ObjectId id) {
        String msg = messagesApi.messagesTop(id);
        return msg;
    }

    /**
     * 消息取消置顶
     *
     * @param id
     * @return
     */
    public String messagesUntop(ObjectId id) {
        String msg = messagesApi.messagesUntop(id);
        return msg;
    }

    /**
     * 消息拒绝
     *
     * @return
     */
    public String messagesReject(String[] ids) {
        String msg = messagesApi.messagesReject(ids);
        return msg;
    }

    /**
     * 消息撤销
     *
     * @return
     */
    public String revocation(String[] ids) {
        String msg = messagesApi.revocation(ids);
        return msg;
    }

    /**
     * 消息翻页
     *
     * @param page
     * @param pagesize
     * @param sortProp
     * @param sortOrder
     * @param id
     * @param sd
     * @param ed
     * @param uid
     * @param state
     * @return
     */
    public PageMessagesVo pageMessages(Integer page, Integer pagesize, String sortProp, String sortOrder,
                                       String id, Long sd, Long ed, Integer uid, String state) {

        //将前端参数进行封装
        MsgQuery msgQuery = new MsgQuery(sortProp, sortOrder, id, sd, ed, uid, state);

        //调用dubbo 获取动态表集合
        List<Publish> publishList = messagesApi.pagePublishMessages(page, pagesize, msgQuery);

        //创建动态信息集合
        List<MessagesVo> messagesVoList = new ArrayList<>();

        //遍历动态信息并封装到集合中
        for (Publish publish : publishList) {
            MessagesVo messagesVo = new MessagesVo();
            messagesVo.setId(publish.getId().toHexString());
            messagesVo.setUserId(Convert.toInt(publish.getUserId()));
            messagesVo.setText(publish.getText());
            messagesVo.setMedias(publish.getMedias().toArray(new String[0]));
            messagesVo.setTopState(publish.getTopState());
            messagesVo.setState(publish.getState().toString());
            messagesVo.setCreateDate(publish.getCreated());

            //获取动态用户的个人信息
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, publish.getUserId());
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);

            //将动态作者的个人信息复制到messagesVo类中
            fillUserInfoToMessagesVo(userInfo, messagesVo,publish);
            //将封装好的动态信息加入到集合中
            messagesVoList.add(messagesVo);
        }

        //创建状态表集合
        List<TotalsVo> totalsVoList = new ArrayList<>();
        //将状态栏信息封装到集合中
        totalsVoList.add(getTotalsVo(TitleStateType.all, TotalsStateType.all,msgQuery));
        totalsVoList.add(getTotalsVo(TitleStateType.NotReviewed, TotalsStateType.NotReviewed,msgQuery));
        totalsVoList.add(getTotalsVo(TitleStateType.Reviewed, TotalsStateType.Reviewed,msgQuery));
        totalsVoList.add(getTotalsVo(TitleStateType.Rejected, TotalsStateType.Rejected,msgQuery));

        //获取当前状态下所有动态数
        Long count = messagesApi.queryCount(page, pagesize,msgQuery);
        //获取总页数
        Integer pages = PageUtil.totalPage(Convert.toInt(count), pagesize);
        //封装页面信息及动态信息
        PageMessagesVo pageMessagesVo = new PageMessagesVo();
        pageMessagesVo.setCounts(Convert.toInt(count));
        pageMessagesVo.setPages(pages);
        pageMessagesVo.setPage(page);
        pageMessagesVo.setPagesize(pagesize);
        pageMessagesVo.setItems(messagesVoList);
        pageMessagesVo.setTotals(totalsVoList);

        return pageMessagesVo;
    }


    /**
     * 状态栏信息
     *
     * @param titleType
     * @param totalsType
     * @return
     */
    private TotalsVo getTotalsVo(TitleStateType titleType, TotalsStateType totalsType,MsgQuery msgQuery) {
        TotalsVo totalsVo = new TotalsVo();
        totalsVo.setTitle(titleType.getType());
        totalsVo.setCode(totalsType.getType());
        Long count = messagesApi.queryStateCount(totalsType.getType(),msgQuery);

        totalsVo.setValue(Convert.toInt(count));
        return totalsVo;
    }


    /**
     * 消息详情
     *
     * @param id
     * @return
     */
    public MsgVo queryMessages(String id) {

        //调用dubbo 获取动态表集合
        Publish publish = messagesApi.queryComment(id);


        //将动态信息封装到MessagesVo中
        MsgVo msgVo = new MsgVo();
        msgVo.setId(publish.getId().toHexString());
        msgVo.setUserId(Convert.toInt(publish.getUserId()));
        msgVo.setText(publish.getText());
        msgVo.setMedias(publish.getMedias().toArray(new String[0]));
        msgVo.setTopState(publish.getTopState());
        msgVo.setState(publish.getState());
        msgVo.setCreateDate(publish.getCreated());

        //获取动态用户的个人信息
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getUserId, publish.getUserId());
        UserInfo userInfo = userInfoMapper.selectOne(wrapper);

        //将动态作者的个人信息复制到messagesVo类中
        BeanUtil.copyProperties(userInfo, msgVo, "id");
        msgVo.setNickname(userInfo.getNickName()); //昵称
        msgVo.setUserLogo(userInfo.getLogo());//头像

        //判断点赞数和评论数是否需要更新,并获取点赞数和评论数
        Map<String, Long> map = updateCount(msgVo.getId(), publish);

        //点赞数
        msgVo.setLikeCount(Convert.toInt(map.get("likeCount")));
        //评论数
        msgVo.setCommentCount(Convert.toInt(map.get("commentCount")));



        /*msgVo.setLikeCount(Convert.toInt(quanZiApi.queryLikeCount(msgVo.getId()))); //TODO 点赞数
        msgVo.setCommentCount(Convert.toInt(quanZiApi.queryCommentCount(msgVo.getId()))); //TODO 评论数*/


        msgVo.setReportCount(0);//TODO 举报数
        msgVo.setForwardingCount(0);//TODO 转发数
        return msgVo;
    }

    //填充用户信息
    private void fillUserInfoToMessagesVo(UserInfo userInfo, MessagesVo messagesVo,Publish publish) {
        BeanUtil.copyProperties(userInfo, messagesVo, "id");

        messagesVo.setNickname(userInfo.getNickName()); //昵称
        messagesVo.setUserLogo(userInfo.getLogo());//头像

        //判断点赞数和评论数是否需要更新,并获取点赞数和评论数
        Map<String, Long> map = updateCount(messagesVo.getId(), publish);

        /*messagesVo.setLikeCount(Convert.toInt(quanZiApi.queryLikeCount(messagesVo.getId()))); //TODO 点赞数
        messagesVo.setCommentCount(Convert.toInt(quanZiApi.queryCommentCount(messagesVo.getId()))); //TODO 评论数
        */

        //点赞数
        messagesVo.setLikeCount(Convert.toInt(map.get("likeCount")));
        //评论数
        messagesVo.setCommentCount(Convert.toInt(map.get("commentCount")));
        messagesVo.setReportCount(0);//TODO 举报数
        messagesVo.setForwardingCount(0);//TODO 转发数

    }

    //判断点赞数和评论数是否更新
    public Map<String, Long> updateCount(String publishId, Publish publish){
        Long likeCount = quanZiApi.queryLikeCount(publishId);
        if (!likeCount.equals(Convert.toLong(publish.getLikeCount()))) {
            messagesApi.updateLikeCount(publishId,likeCount);
        }

        Long commentCount = quanZiApi.queryCommentCount(publishId);
        if (!commentCount.equals(Convert.toLong(publish.getCommentCount()))) {
            messagesApi.updateCommentCount(publishId,commentCount);
        }

        Map<String, Long> map = new HashMap<>();
        map.put("likeCount", likeCount);
        map.put("commentCount", commentCount);
        return map;
    }

}
